package uk.ac.strath.cis.metric_spaces.distance;

import uk.ac.strath.cis.collections.Point;
import uk.ac.strath.cis.collections.Point.PointImpl;
import uk.ac.strath.cis.metric_spaces.framework.Distance;

public class CosineDistance extends PointDistance {

	public double distance(Point p1, Point p2) {
		double dot = super.distance(p1, p2);
		double mag = rootSumOfSquares(p1) * rootSumOfSquares(p2);
		return (2 * Math.acos((dot / mag)) / Math.PI);
	}

	private double rootSumOfSquares(Iterable<Double> it) {
		double results = 0.0;
		for (double d : it) {
			results += Math.pow(d, 2);
		}
		return Math.sqrt(results);
	}

	@Override
	protected double algorithm(double acc, double n1, double n2) {
		acc += n1 * n2;
		return acc;
	}

	@Override
	public String toString() {
		return "Cosine Distance";
	}

	public static void main(String[] args) {
		Distance<Point> d = new CosineDistance();
		System.out.println(d.distance(PointImpl.create(1.0, 2.0, 3.0),
				PointImpl.create(3.0, 5.0, 7.0)));
	}

}
